package message.visitor.tests;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import junit.framework.Assert;
import message.MessageParser;
import message.types.data.AddDataRequest;
import message.types.data.GetAllDatasAnswer;
import message.types.data.GetLastDataAnswer;
import message.types.message.RejectedRequest;
import message.types.none.GetAllDatasRequest;
import message.types.none.GetLastDataRequest;
import message.types.none.NewDataNotification;
import message.types.stalker.LoginSuccessAnswer;
import message.types.stalker.RegisterRequest;
import message.types.stalkerstring.GetRoomFromNameAnswer;
import message.types.stalkerstring.GetUserFromNameAnswer;
import message.types.string.CreatePrivatePersistentRoomRequest;
import message.types.string.CreateRoomRequest;
import message.types.string.GetRoomFromNameRequest;
import message.types.string.GetUserFromNameRequest;
import message.types.unique.EmptyMessage;
import message.types.unique.RoomInvitation;
import network.e2e.FrameReader;
import network.e2e.FrameWriter;
import network.link.FrameInputStream;
import network.link.FrameOutputStream;

import org.junit.Test;

import stalker.Stalker;
import stalker.tester.TesterStalker;
import stalker.user.User;
import data.Data;
import data.content.Content;
import data.content.ContentSentence;
import data.datas.CompleteHistoryDatas;
import data.datas.Datas;


public class UserMessageVisitorTest {
  
  @Test
  public void test01() throws InterruptedException, IOException {
    
    FrameReader tread, reader;
    FrameWriter writer;
    tread = new FrameReader(new FrameInputStream(System.in));
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    writer = new FrameWriter(new FrameOutputStream(bytes));
    
    TesterStalker tester = new TesterStalker();
    
    //writer simulates net
    User src = User.createUser("Nur Ulfa Maulidevi");
    
    src.activate(tread, writer);
    
    Content test_content = new ContentSentence("Love");
    Data test_data = new Data(src, test_content);
    Datas test_datas = new CompleteHistoryDatas();
    test_datas.insertData(test_data);
    
    src.acceptMessage(
        new AddDataRequest(src, tester, test_content)
        );
    Thread.sleep(25);
    Assert.assertTrue(tester.isMessage(
        new AddDataRequest(src, tester, test_content)
        ));
    Thread.sleep(25);
    src.acceptMessage(
        new GetLastDataRequest(src, tester)
        );
    Thread.sleep(25);
    Assert.assertTrue(tester.isMessage(
        new GetLastDataRequest(src, tester)
        ));
    
    Thread.sleep(25);
    src.acceptMessage(
        new GetLastDataAnswer(tester, src, test_data)
        );
    
    Thread.sleep(25);
    src.acceptMessage(
        new RegisterRequest(src, tester, src)
        );
    Thread.sleep(25);
    Assert.assertTrue(tester.isMessage(
        new RegisterRequest(src, tester, src)
        ));
    
    Thread.sleep(25);
    src.acceptMessage(
        new EmptyMessage()
        );
    
    Thread.sleep(25);
    src.acceptMessage(
        new LoginSuccessAnswer(Stalker.LOGIN_MANAGER_STALKER, src, src)
        );
    
    Thread.sleep(25);
    src.acceptMessage(
        new CreateRoomRequest(src, tester, "itb")
        );
    Thread.sleep(25);
    Assert.assertTrue(tester.isMessage(
        new CreateRoomRequest(src, tester, "itb")
        ));
    
    Thread.sleep(25);
    src.acceptMessage(
        new CreatePrivatePersistentRoomRequest(src, tester, "itb")
        );
    Thread.sleep(25);
    Assert.assertTrue(tester.isMessage(
        new CreatePrivatePersistentRoomRequest(src, tester, "itb")
        ));
    
    System.out.println("cp0");
    
    Thread.sleep(25);
    src.acceptMessage(
        new RoomInvitation(tester, src, tester, src)
        );
    
    System.out.println("cp1");
    
    Thread.sleep(25);
    src.acceptMessage(
        new GetAllDatasRequest(src, tester)
        );
    Thread.sleep(25);
    Assert.assertTrue(tester.isMessage(
        new GetAllDatasRequest(src, tester)
        ));
    
    System.out.println("cp2");
    
    Thread.sleep(25);
    src.acceptMessage(
        new GetAllDatasAnswer(tester, src, test_datas)
        );
    
    Thread.sleep(25);
    src.acceptMessage(
        new GetUserFromNameRequest(src, tester, "Kya")
        );
    Thread.sleep(25);
    Assert.assertTrue(tester.isMessage(
        new GetUserFromNameRequest(src, tester, "Kya")
        ));
    
    Thread.sleep(25);
    src.acceptMessage(
        new GetUserFromNameAnswer(Stalker.USER_MANAGER, src, src, "Kya")
        );
    
    Thread.sleep(25);
    src.acceptMessage(
        new NewDataNotification(tester, src)
        );
    Thread.sleep(25);
    
    Thread.sleep(25);
    src.acceptMessage(
        new GetRoomFromNameRequest(src, tester, "Kya")
        );
    Thread.sleep(25);
    Assert.assertTrue(tester.isMessage(
        new GetRoomFromNameRequest(src, tester, "Kya")
        ));
    Thread.sleep(25);
    
    
    src.acceptMessage(
        new GetRoomFromNameAnswer(Stalker.USER_MANAGER, src, src, "Kya")
        );
    Thread.sleep(25);
    
    src.acceptMessage(
        new RejectedRequest(src, tester, new EmptyMessage())
        );
    Thread.sleep(25);
    Assert.assertTrue(tester.isMessage(new RejectedRequest(src, tester, new EmptyMessage())));
    Thread.sleep(25);
    src.acceptMessage(
        new RejectedRequest(tester, src, new EmptyMessage())
        );
    Thread.sleep(25);
    
    reader = new FrameReader(new FrameInputStream(new ByteArrayInputStream(bytes.toByteArray())));
    
    System.out.println(new String(bytes.toByteArray()));
    
    Assert.assertTrue(MessageParser.retrieve(reader).equals(
        new GetLastDataAnswer(tester, src, test_data)
        ));
    
    Assert.assertTrue(MessageParser.retrieve(reader).equals(
        new LoginSuccessAnswer(Stalker.LOGIN_MANAGER_STALKER, src, src)
        ));
    
    Assert.assertTrue(MessageParser.retrieve(reader).equals(
        new RoomInvitation(tester, src, tester, src)
        ));
    Assert.assertTrue(MessageParser.retrieve(reader).equals(
        new GetAllDatasAnswer(tester, src, test_datas)
        ));
    Assert.assertTrue(MessageParser.retrieve(reader).equals(
        new GetUserFromNameAnswer(Stalker.USER_MANAGER, src, src, "Kya")
         ));
    Assert.assertTrue(MessageParser.retrieve(reader).equals(
        new NewDataNotification(tester, src)
         ));
    Assert.assertTrue(MessageParser.retrieve(reader).equals(
        new GetRoomFromNameAnswer(Stalker.USER_MANAGER, src, src, "Kya")
         ));
    Assert.assertTrue(MessageParser.retrieve(reader).equals(
        new RejectedRequest(tester, src, new EmptyMessage())
         ));
    
  }
  
}
